home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / vbcc.lha / vbcc / av.c < prev    next >
C/C++ Source or Header  |  1997-12-30  |  12KB  |  309 lines

  1. /*  $VER: vbcc (av.c) V0.4     */
  2. /*  aktive Variablen und Elimination unnoetiger Anweisungen */
  3.  
  4. #include "opt.h"
  5.  
  6. static char FILE_[]=__FILE__;
  7.  
  8. /*  fuer aktive Variablen   */
  9. struct Var **vilist;
  10. unsigned int vcount;    /*  0..vcount-rcount-1: vars, vcount-rcount..vcount: DREFOBJs */
  11. unsigned int rcount;
  12. size_t vsize;
  13. unsigned char *av_globals,*av_address,*av_statics,*av_drefs;
  14. int report_dead_statements;
  15.  
  16. void print_av(unsigned char *bitvector)
  17. /*  druckt Variablen in einem Bitvektor */
  18. {
  19.     int i;
  20.     if(!bitvector) {printf("active variables not available\n");return;}
  21.     for(i=0;i<vcount-rcount;i++)
  22.         if(BTST(bitvector,i)) printf("%3d: %s,%ld\n",i,vilist[i]->identifier,zl2l(vilist[i]->offset));
  23.     for(i=vcount-rcount;i<vcount;i++)
  24.         if(BTST(bitvector,i)) printf("%3d: (%s),%ld\n",i,vilist[i]->identifier,zl2l(vilist[i]->offset));
  25. }
  26. void num_vars(void)
  27. /*  Numeriert Variablen und erzeugt Indexliste  */
  28. {
  29.     unsigned int i,j;struct IC *p;struct Var *v,*a[3],*vp;
  30.     if(DEBUG&1024) printf("numerating variables loop1\n");
  31.     /*  alle Indizes auf -1 */
  32.     a[0]=vl1;
  33.     a[1]=vl2;
  34.     a[2]=vl3;
  35.     for(j=0;j<3;j++){
  36.         v=a[j];
  37.         while(v){
  38.             v->index=-1;
  39.             /*  Variablen von inline-Funktionen */
  40.             if(j==0&&v->fi&&v->fi->first_ic){
  41.                 for(vp=v->fi->vars;vp;vp=vp->next) vp->index=-1;
  42.             }
  43.             v=v->next;
  44.         }
  45.     }
  46.     /*  erst alle Variablen, die als DREFOBJ benutzt werden */
  47.     if(DEBUG&1024) printf("numerating variables loop2\n");
  48.     i=0;
  49.     for(p=first_ic;p;p=p->next){
  50.         if(p->code<LABEL||p->code>BRA){
  51.             int c=p->code;
  52.             j=p->typf&NQ;
  53.             if(c==SUBPFP) j=POINTER;
  54.             if(c==ADDI2P||c==SUBIFP) j=POINTER;
  55.             if(c==CONVCHAR||c==CONVUCHAR) j=CHAR;
  56.             if(c==CONVSHORT||c==CONVUSHORT) j=SHORT;
  57.             if(c==CONVINT||c==CONVUINT) j=INT;
  58.             if(c==CONVLONG||c==CONVULONG) j=LONG;
  59.             if(c==CONVPOINTER) j=POINTER;
  60.             if(c==CONVFLOAT) j=FLOAT;
  61.             if(c==CONVDOUBLE) j=DOUBLE;
  62.             if((p->q1.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)){
  63.                 v=p->q1.v;
  64.                 if(!v->vtyp->next||(v->vtyp->next->flags&NQ)!=j) v->flags|=DNOTTYPESAFE;
  65.                 if(v->index<0) v->index=i++;
  66.             }
  67.             j=p->typf&NQ;
  68.             if(c==SUBPFP) j=POINTER;
  69.             if((p->q2.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)){
  70.                 v=p->q2.v;
  71.                 if(!v->vtyp->next||(v->vtyp->next->flags&NQ)!=j) v->flags|=DNOTTYPESAFE;
  72.                 if(v->index<0) v->index=i++;
  73.             }
  74.             j=p->typf&NQ;
  75.             if(c==ADDI2P||c==SUBIFP) j=POINTER;
  76.             if((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)){
  77.                 v=p->z.v;
  78.                 if(!v->vtyp->next||(v->vtyp->next->flags&NQ)!=j) v->flags|=DNOTTYPESAFE;
  79.                 if(v->index<0) v->index=i++;
  80.             }
  81.         }
  82.     }
  83.     if(DEBUG&1024) printf("numerating variables loop3\n");
  84.     rcount=i;    /*  Anzahl der DREFOBJ-Variablen    */
  85.     /*  jetzt den Rest  */
  86.     for(p=first_ic;p;p=p->next){
  87.         if(1/*p->code<LABEL||p->code>BRA*/){
  88.             j=p->typf&NQ;
  89.             if((p->q1.flags&(VAR|DREFOBJ))==VAR){
  90.                 v=p->q1.v;
  91.                 if((v->vtyp->flags&NQ)!=j) v->flags|=NOTTYPESAFE;
  92.                 if(v->index<0) v->index=i++;
  93.             }
  94.             if((p->q2.flags&(VAR|DREFOBJ))==VAR){
  95.                 v=p->q2.v;
  96.                 if((v->vtyp->flags&NQ)!=j) v->flags|=NOTTYPESAFE;
  97.                 if(v->index<0) v->index=i++;
  98.             }
  99.             if((p->z.flags&(VAR|DREFOBJ))==VAR){
  100.                 v=p->z.v;
  101.                 if((v->vtyp->flags&NQ)!=j) v->flags|=NOTTYPESAFE;
  102.                 if(v->index<0) v->index=i++;
  103.             }
  104.         }
  105.     }
  106.     if(DEBUG&1024) printf("numerating variables loop4\n");
  107.     vcount=i+rcount; /*  alle benutzten Variablen+Anzahl der DREFOBJs    */
  108.     vilist=mymalloc(vcount*sizeof(struct Var *));
  109.     for(j=0;j<3;j++){
  110.         int i;
  111.         v=a[j];
  112.         while(v){
  113.             i=v->index;
  114. /*            printf("%s has index %d\n",v->identifier,i);*/
  115.             if(i>=0){
  116.                 if(i>=vcount-rcount) ierror(0);
  117.                 vilist[i]=v;
  118.                 if(i<rcount) vilist[i+vcount-rcount]=v;
  119.             }
  120.             /*  Variablen von inline-Funktionen */
  121.             if(j==0&&v->fi&&v->fi->first_ic){
  122.                 for(vp=v->fi->vars;vp;vp=vp->next){
  123.                     i=vp->index;
  124.                     if(i>=0){
  125.                         if(i>=vcount-rcount) ierror(0);
  126.                         vilist[i]=vp;
  127.                         if(i<rcount) vilist[i+vcount-rcount]=vp;
  128.                     }
  129.                 }
  130.             }
  131.             v=v->next;
  132.         }
  133.     }
  134.  
  135.     vsize=(vcount+CHAR_BIT-1)/CHAR_BIT;
  136.     if(DEBUG&1024) printf("%lu variables (%lu DREFOBJs), vsize=%lu\n",(unsigned long)vcount,(unsigned long)rcount,(unsigned long)vsize);
  137.  
  138.     av_drefs=mymalloc(vsize);
  139.     memset(av_drefs,0,vsize);
  140.     /*  alle DREFOBJs   */
  141.     for(i=vcount-rcount;i<vcount;i++) BSET(av_drefs,i);
  142.  
  143.     /*  av_globals enthaelt alle globalen Variablen und av_address      */
  144.     /*  zusaetzlich noch alle Variablen, deren Adressen genommen wurden */
  145.     av_globals=mymalloc(vsize);
  146.     memset(av_globals,0,vsize);
  147.     av_statics=mymalloc(vsize);
  148.     memset(av_statics,0,vsize);
  149.     av_address=mymalloc(vsize);
  150.     memcpy(av_address,av_globals,vsize);
  151.     for(i=0;i<vcount-rcount;i++){
  152.         if(vilist[i]->nesting==0||vilist[i]->storage_class==EXTERN) BSET(av_globals,i);
  153.         if(vilist[i]->flags&USEDASADR) BSET(av_address,i);
  154.         if(vilist[i]->storage_class==STATIC) BSET(av_statics,i);
  155.         if(i<rcount){
  156. /*            if((vilist[i]->vtyp->flags&NQ)!=POINTER){ printf("%s(%ld)\n",vilist[i]->identifier,zl2l(vilist[i]->offset));ierror(0);}*/
  157.             BSET(av_address,i+vcount-rcount);
  158.             BSET(av_globals,i+vcount-rcount);
  159.         }
  160.     }
  161. }
  162. void print_vi(void)
  163. /*  Druckt vilist und testet Konsistenz */
  164. {
  165.     int i;
  166.     printf("\nprint_vi()\n");
  167.     for(i=0;i<vcount;i++){
  168.         if(!vilist[i]||(i<rcount&&vilist[i]->index!=i)) ierror(0);
  169.         printf("%3d: %s\n",i,vilist[i]->identifier);
  170.     }
  171. }
  172. void av_change(struct IC *p,unsigned char *use,unsigned char *def)
  173. /*  Berechnet die Aenderungen, die sich durch IC p an use und def ergeben.  */
  174. {
  175.     int i,j,n=-1;
  176.     int g1,g2;
  177.  
  178.     /*  Wenn eine Quelle==Ziel, dann wird dadurch kein neuer use erzeugt,   */
  179.     /*  um z.B. unbenutzte Induktionsvariablen in Schleifen zu eliminieren. */
  180.     g1=compare_objs(&p->q1,&p->z,p->typf);
  181.     g2=compare_objs(&p->q2,&p->z,p->typf);
  182.     if(!g1&&(p->q1.flags&(VAR|DREFOBJ))==VAR) n=p->q1.v->index;
  183.     if(!g2&&(p->q2.flags&(VAR|DREFOBJ))==VAR) n=p->q2.v->index;
  184.  
  185.     for(j=0;j<p->use_cnt;j++){
  186.         i=p->use_list[j].v->index;
  187.         if(p->use_list[j].flags&DREFOBJ) i+=vcount-rcount;
  188.         if(i>=vcount) continue;
  189.         if(i!=n&&!BTST(def,i)) BSET(use,i);
  190.     }
  191.  
  192.     /*  Ein Wert wird nicht zerstoert, wenn es kein elementarer Typ ist und */
  193.     /*  die Groesse kleiner als die Variable (steht in alle solchen ICs in  */
  194.     /*  q2.val.vlong.                                                       */
  195.     if((p->z.flags&(VAR|DREFOBJ))==VAR&&g1&&g2&&((p->z.v->vtyp->flags&NQ)<=POINTER||zleqto(p->q2.val.vlong,szof(p->z.v->vtyp)))){
  196.         i=p->z.v->index;
  197.         if(i>=vcount) ierror(0);
  198.         if(!BTST(use,i)) BSET(def,i);
  199.         /*  Wenn p geaendert wird, wird auch *p geaendert   */
  200.         if(i<rcount&&!BTST(def,i+vcount-rcount)) BSET(use,i+vcount-rcount);
  201.     }
  202.     if((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)&&g1&&g2){
  203.         i=p->z.v->index+vcount-rcount;
  204.         if(i>=vcount) ierror(0);
  205.         if(!BTST(use,i)) BSET(def,i);
  206.     }
  207. }
  208. void active_vars(struct flowgraph *fg)
  209. /*  analysiert aktive Variablen im Flussgraphen, nomain==0, wenn zu     */
  210. /*  optimierende Funktion main() ist                                    */
  211. {
  212.     struct IC *p;
  213.     int changed,pass;struct flowgraph *g;
  214.  
  215.     if(DEBUG&1024){printf("analysing active variables\n");/*scanf("%d",&i);*/}
  216.     tmp=mymalloc(vsize);
  217.     /*  av_gen und av_kill fuer jeden Basic Block berechnen